<?php
namespace App\Repositories;

use DB;
use App\Interfaces\RefundGoodsService;
use App\Interfaces\RefundGoodsOperationRecordService;
use App\Exceptions\Interfaces\RefundGoodsServiceException;
use App\Interfaces\StockService;
use App\Interfaces\GoodsStockHistoryService;

use App\Models\RefundGoods;
use App\Models\Order;
use App\Models\OrderGoods;


class RefundGoodsRepository  implements RefundGoodsService{

    private $refundGoodsOperationRecordService;

    private $stockService;

    private $goodsStockHistoryService;

    public function __construct(RefundGoodsOperationRecordService $refundGoodsOperationRecordService, StockService $stockService, GoodsStockHistoryService $goodsStockHistoryService)
    {

        $this->refundGoodsOperationRecordService = $refundGoodsOperationRecordService;

        $this->stockService = $stockService;

        $this->goodsStockHistoryService = $goodsStockHistoryService;

    }

    /*
     * 创建收货服务单
     * @param string $order_sn              订单编号
     * @param int $goods_id                 商品id
     * @param int $order_goods_id           订单商品表id
     * @param string $goods_sn              商品编号
     * @param mediumint $number             商品数量
     * @param int $user_id                  申请售后的用户id
     * @param string $real_name             用户真实姓名（从前台得到的）
     * @param string $phone                 用户的电话号码，与购买时所用的号码一致
     * @param decimal $shop_price           商品单价
     * @param decimal $goods_real_price     商品折扣后的单价
     * @param string $reason                退货原因
     * @param string $remark                售后备注信息
     *
     * @date:2016/02/18
     * @author:Leen
     */
    public function createReturnGoods($user_id, $order_sn, $goods_id, $order_goods_id, $goods_sn, $number, $real_name, $phone, $shop_price, $goods_real_price, $reason='', $remark='', RefundGoodsOperationRecordService $refundGoodsOperationRecordService){
        $refund_sn = $this->makeRefundSn();         //退货服务编号
        $refund_status = 1;      //售后服务状态

        if(empty($user_id)){
            throw new RefundGoodsServiceException('申请售后的用户id不能为空');
        }//end if()

        if(empty($order_sn)){
            throw new RefundGoodsServiceException('申请售后的订单编号不能为空');
        }//end if()

        if(empty($order_goods_id)){
            throw new RefundGoodsServiceException('申请售后的订单商品表id不能为空');
        }//end if()

        if(empty($goods_sn)){
            throw new RefundGoodsServiceException('申请售后的商品编号不能为空');
        }//end if()

        if(empty($number) || $number<1){
            throw new RefundGoodsServiceException('申请售后的商品数量不能小于1');
        }//end if()

        if(empty($real_name)){
            throw new RefundGoodsServiceException('申请售后的用户姓名不能为空');

        }elseif(!empty($real_name) && mb_strlen(trim($real_name))>255 ){
            throw new RefundGoodsServiceException('申请售后的用户姓名长度不能大于255个字符');

        }//end if()

        if(empty($phone)){
            throw new RefundGoodsServiceException('申请售后的用户联系电话不能为空');
        }//end if()-

        if($shop_price<0){
            throw new RefundGoodsServiceException('申请售后的订单商品单价不能小于0');
        }//end if()

        if(!empty($reason) && mb_strlen(trim($reason))>255 ){

            throw new RefundGoodsServiceException('售后原因不能大于255个字符');
        }//end if()

        if(!empty($remark) && mb_strlen(trim($remark))>255 ){
            throw new RefundGoodsServiceException('售后备注内容不能大于255个字符');
        }//end if()


        $coupon_price_offset = 0.00;              //本次退货可以抵消的优惠券金额

        $orders = Order::where('order_sn', $order_sn)->first();

        $order_id = $orders->order_id;

        $order_goods_arr = OrderGoods::where('order_id', $order_id)->get();

        if($order_goods_arr->count() > 0){

            $order_coupon_price = $orders->coupon_price;        //订单中使用的优惠券总金额

            $coupon_price_already_offset = 0;                   //订单中其他商品退货已经抵消的优惠券金额

            foreach ($order_goods_arr as $key => $value) {

                $refund_goods = RefundGoods::where('order_sn', $order_sn)->where('goods_id', $value->goods_id)->first();

                if($refund_goods){         //该商品已经申请过售后

                    $coupon_price_already_offset += $refund_goods->coupon_price_offset;
                }
            }

            $coupon_price_already_offset = sprintf("%.2f",substr(sprintf("%.3f", $coupon_price_already_offset), 0, -1));

            if ($goods_real_price * $number >= $order_coupon_price - $coupon_price_already_offset) {

                $coupon_price_offset = $order_coupon_price - $coupon_price_already_offset;

            }else{

                $coupon_price_offset = $goods_real_price * $number;
            }
        }

        $refund_id = RefundGoods::insertGetId([
            'refund_sn'=>$refund_sn,
            'order_sn'=>$order_sn,
            'goods_id'=>$goods_id,
            'order_goods_id'=>$order_goods_id,
            'goods_sn'=>$goods_sn,
            'number'=>$number,
            'refund_status'=>$refund_status,
            'user_id'=>$user_id,
            'real_name'=>$real_name,
            'phone'=>$phone,
            'shop_price'=>$shop_price,
            'goods_real_price'=>$goods_real_price,

            'coupon_price_offset'=>$coupon_price_offset,

            'reason'=>$reason,
            'remark'=>$remark
        ]);


        if(empty($refund_id)){
            throw new RefundGoodsServiceException('售后（退货）申请失败');
        }else{

            //加售后服务操作记录
            $refund_sn = RefundGoods::where('refund_id', $refund_id)->pluck('refund_sn');
            $operation_status = 1;        //操作类型
            $operation_time = date('Y-m-d H:i:s', time());
            $users_id = 0;           //表示系统创建
            $refundGoodsOperationRecordService->createRefundGoods($refund_sn, $operation_status, $operation_time, $users_id);

            return $refund_id;
        }//end if()


    }//end func createReturnGoods()

    /**
     * 更新服务单
     *
     * @param int $users_id             当前操作用户的id; users_id=0 表示系统创建
     * @param string $refund_sn         服务单编号
     * @param tinyint $refund_status    售后服务状态
     * @param string $real_name         用户真实姓名（从前台得到的）
     * @param string $phone             用户的电话号码，与购买时所用的号码一致
     * @param string $remark            售后备注信息
     *
     * @date:2016/02/18
     * @author Leen
     */
    public function updateReturnGoods($users_id, $refund_sn, $refund_status, $real_name='', $phone='', $remark=''){

        $contentArr = [];

        if(empty($refund_sn)){
            throw new RefundGoodsServiceException('售后服务单号不能为空');
        }//end if()

        if(!empty($refund_status)){
            $contentArr['refund_status'] = $refund_status;
        }else{
            throw new RefundGoodsServiceException('单号状态不能为空');
        }//end if()

        if(!empty($real_name) && mb_strlen(trim($real_name))<=255 ){
            $contentArr['real_name'] = $real_name;

        }elseif(!empty($real_name) && mb_strlen(trim($real_name))>255 ){
            throw new RefundGoodsServiceException('申请售后的用户姓名长度不能大于255个字符');

        }//end if()

        if(!empty($phone)){
            $contentArr['phone'] = $phone;
        }//end if()

        if(!empty($remark) && mb_strlen(trim($remark))<=255 ){
            $contentArr['remark'] = $remark;
        }elseif(!empty($remark) && mb_strlen(trim($remark))>255 ){
            throw new RefundGoodsServiceException('售后备注内容不能大于255个字符');
        }//end if()

        RefundGoods::where('refund_sn', $refund_sn)->update($contentArr);

        //加售后服务操作记录
        switch(trim($refund_status)){
            case 2:
                $operation_status = 2;        //售后服务操作类型：1:申请退货; 2:受理退货；3:完成退货；4:不予退货；5:取消退货
                break;

            case 3:
                $operation_status = 3;

                //处理完毕返还库存
                $goods_stock = 1;
                $operation = 'plus';
                $describe = '退货处理完毕返还库存';

                $refundInfo = $this->getByRefundSn($refund_sn);
                $goods_sn = $refundInfo->goods_sn;
                $goods_id = $refundInfo->goods_id;
                $this->stockService->updateStock($goods_id, $users_id, $goods_stock, $operation, $describe, $this->goodsStockHistoryService);
                break;

            case 4:
                $operation_status = 4;
                break;

            case 5:
                $operation_status = 5;
                break;

        }//end switch()

        $operation_time = date('Y-m-d H:i:s', time());
        $this->refundGoodsOperationRecordService->createRefundGoods($refund_sn, $operation_status, $operation_time, $users_id);

        //return RefundGoods::where('refund_sn', $refund_sn)->update($contentArr);
        return true;

    }//end func updateReturnGoods()


    /**
     * 取消退货申请
     * @param $order_id
     * @param $reason
     * @return mixed
     */
    public function cancelReturnGoods($refund_sn, $refund_status){

    }//end func cancelReturnGoods()


    /**
     * 根据服务单号获取服务单信息
     *
     * @param string $refund_sn         服务单编号
     *
     * @date:2016/02/26
     * @author Leen
     */
    public function getByRefundSn($refund_sn){
        $refundGoods = RefundGoods::where('refund_sn', $refund_sn)->first();

        return $refundGoods;
    }//end func getByRefundSn()

    /**
     * 根据订单号和订单商品编码获取服务单信息
     *
     * @param string $refund_sn         服务单编号
     *
     * @date:2016/02/26
     * @author Leen
     */
    public function getByOrderSnGoodsSn($order_sn, $goods_sn){
        $refundGoods = RefundGoods::where('order_sn', $order_sn)->where('goods_sn', $goods_sn)->first();

        return $refundGoods;
    }//end func getByRefundSn()


    /**
     * 生成售后单号
     *
     * @return string
     */
    public function makeRefundSn() {
        $year_code = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
        $refund_sn = $year_code[intval(date('Y'))-1999].strtoupper(dechex(date('m'))).date('d').substr(time(),-5).substr(microtime(),2,5).sprintf('d',rand(0,99));
        return $refund_sn;
    }//end func makeRefundSn()

    public function countRefundGoods($user_id){
        return RefundGoods::where('user_id',$user_id)->count();
    }

    public function countRefundGoodsNum($user_id){
        return RefundGoods::where('user_id',$user_id)->where(function($query){
                        $query->where('refund_status',1)->orWhere('refund_status',2);
                })->count();

    }


    /**
     * 判断订单商品是否申请过售后
     * @param [type] $order_sn [description]
     * @param [type] $goods_id [description]
     */
    public function isHasRefund($order_sn, $goods_id)
    {

        return RefundGoods::where('order_sn', $order_sn)->where('goods_id', $goods_id)->first();
    }
}